package socofwebget;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

public class Coleccao {

    private List<Ficheiro> lista = Collections.synchronizedList(new ArrayList<Ficheiro>()) ;

      List list = Collections.synchronizedList(new ArrayList());

    
    public Coleccao() {
    }
/**
 * Devolve AL com todos os FX existentes na BD do dominio
 * @param dominio Recebe o dominio para o qual queremos os ficheiros
 * @return Devolve um ArrayList de Ficheiro
 */
    public synchronized ArrayList<Ficheiro> getListaTodosFXDominio(String dominio) {
        ArrayList<Ficheiro> listaCompleta = new ArrayList<Ficheiro> ();
        
        DBAccess bd=new DBAccess();
        
        listaCompleta = bd.getByDomain(dominio);
        
        synchronized(lista){
            for (Ficheiro ficheiro : listaCompleta) {
                lista.add(ficheiro);            
            }          
        }
//DEBUG
//        for (Ficheiro fx : listaCompleta) {
//            System.err.println("A lista tem tamanho: "+listaCompleta.size());
//            System.err.println(fx.toString());       
//        }
        notifyAll();
        return listaCompleta;
    }
/**Inserir um ArrayList de Ficheiro na BD
 * @param ArrayList<Ficheiro> fx Recebe um ArrayList de ficheiro
 * @return não devolve nada
 */
    public synchronized void inserirArrayFicheiros(ArrayList<Ficheiro> fx){
        DBAccess bd=new DBAccess();
        
        synchronized(lista){
            for (Ficheiro fxIterator : fx) {
                bd.writeData(fxIterator);
            }
        }
                lista=getListaTodosFXDominio(fx.get(0).getDominio());
        notifyAll();
    }    

 /**Inserir um Ficheiro
 * @param fx objecto Ficheiro para adicionar à BD
 * @return devolve o ID do ficheiro e -1 na eventualidade de erro
 */
    public synchronized int  writeData(Ficheiro fx){
        DBAccess bd=new DBAccess();
        int fxId=bd.writeData(fx);
        
        boolean existe=false;
        synchronized(lista){
            // Se existir, actualiza na lista local
            for (Ficheiro ficheiro : lista) {
                if (ficheiro.getId() == fx.getId()){
                    existe = true;
    //                lista=bd.getCompleteByDomain(fx.getDominio());
                    ficheiro.setFicheirosAtributes(fx.getId(), fx.getDominio(),fx.getFicheiro(),
                            fx.getEstado(), fx.getTamanhosite(), fx.getCaminhosite(),
                            fx.getCaminholocal(), fx.getTipo(), fx.getNiveis(),
                            fx.getActualizado());
                    break;}
                else
                    existe = false;
            }
            if (!existe && fxId!= -1){
                fx.setId(fxId);
                lista.add(fx);}
        }
        notifyAll();
        return fxId;
    }
/**Inserir um Ficheiro com argumentos separados. Devolve -1 na eventualidade de erro. Destina-se mais a utilizacao interna
 * 
 * 
 * @param id int com ID do ficheiro (se nulo será actualizado com o ID da BD)
 * @param dominio String com dominio (www.exemplo.com)
 * @param ficheiro String com o nome do ficheiro (paginas.css)
 * @param estado String com estado
 * @param tamanhosite long com o tamanho do ficheiro no site
 * @param caminhosite String com o caminho completo do ficheiro no site com o nome do ficheiro
 * @param caminholocal String com o caminho completo do ficheiro local com o nome do ficheiro
 * @param tipo  String com o tipo de ficheiro 
 * @param niveis int com o nivel do ficheiro
 * @param actualizado variável do tipo Date com a data da ultima actualizacao
 * @return Devolve um int com o ID de Ficheiro
 */
    private synchronized int writeData(Integer id,String dominio, String ficheiro,String estado,
            long tamanhosite,String caminhosite,String caminholocal,
            String tipo,Integer niveis,Date actualizado) {
        
        Ficheiro fx = new Ficheiro(id,dominio.toLowerCase(),ficheiro,
                estado.toUpperCase(),tamanhosite,caminhosite,caminholocal,
                tipo.toUpperCase(),niveis,actualizado);

        int fxId=writeData(fx);
        
        boolean existe=false;
        synchronized(lista){
            // Se existir, actualiza na lista local
            for (Ficheiro ficheiros : lista) {
                if (ficheiros.getId() == fx.getId()){
                    existe = true;
                    break;}
                else
                    existe = false;
            }
            if (!existe && fxId!= -1){
                fx.setId(fxId);
                lista.add(fx);}
        }
        notifyAll();
        return fxId;
        // return writeData(fx);
    }
/** Escrever todo o AL na BD
 * 
 * @param fxTodos ArrayList de Ficheiro a ser inserido na BD
 */
    public synchronized void  writeDataAll(ArrayList<Ficheiro> fxTodos){
        DBAccess bd=new DBAccess();
            //Vai obter o dominio ao qual se refere (sao todos do mesmo dominio)
        String dominio = fxTodos.get(0).getDominio();
        synchronized(lista){
            bd.writeData(fxTodos);
                //Actualiza a listalocal
            lista = getListaTodosFXDominio(dominio);
        }
        notifyAll();
    }
/**Inserir um Ficheiro apenas
 * @param fx Objecto do tipo Ficheiro
 * @return devolve -1 na eventualidade de erro
 */
    public synchronized int adicionaFx(Ficheiro fx){
        DBAccess bd=new DBAccess();
        int fxId=bd.writeData(fx);
        
        boolean existe=false;
        synchronized(lista){
            // Se existir, actualiza na lista local
            for (Ficheiro ficheiro : lista) {
                if (ficheiro.getId() == fx.getId()){
                    existe = true;
    //                lista=bd.getCompleteByDomain(fx.getDominio());
                    ficheiro.setFicheirosAtributes(fx.getId(), fx.getDominio(),fx.getFicheiro(),
                            fx.getEstado(), fx.getTamanhosite(), fx.getCaminhosite(),
                            fx.getCaminholocal(), fx.getTipo(), fx.getNiveis(),
                            fx.getActualizado());
                    break;}
                else
                    existe = false;
            }
            if (!existe && fxId!= -1){
                fx.setId(fxId);
                lista.add(fx);}
        }
        notifyAll();
        return fxId;
    }
/**Inserir um Ficheiro apenas e recebe o Ficheiro com ID actualizado caso va com ID por preencher
 * @param fx Objecto do tipo Ficheiro
 * @return devolve Ficheiro
 */
//    public  Ficheiro adicionaFx(Ficheiro fx){
//        DBAccess bd=new DBAccess();
//        int fxId=bd.writeData(fx);
//        
//        boolean existe=false;
//        synchronized(lista){
//            // Se existir, actualiza na lista local
//            for (Ficheiro ficheiro : lista) {
//                if (ficheiro.getId() == fx.getId()){
//                    existe = true;
//    //                lista=bd.getCompleteByDomain(fx.getDominio());
//                    ficheiro.setFicheirosAtributes(fx.getId(), fx.getDominio(),fx.getFicheiro(),
//                            fx.getEstado(), fx.getTamanhosite(), fx.getCaminhosite(),
//                            fx.getCaminholocal(), fx.getTipo(), fx.getNiveis(),
//                            fx.getActualizado());
//                    break;}
//                else
//                    existe = false;
//            }
//            if (!existe && fxId!= -1){
//                fx.setId(fxId);
//                lista.add(fx);}
//        }
//        notifyAll();
//        return getFicheiro(fxId);
//    }    
    /** Devolve um Objecto Ficheiro conforme o id
     * @param id int com o ID do objecto que queremos receber
     * @return Ficheiro Objecto do tipo Ficheiro devolvido
     */
    public synchronized Ficheiro getFicheiro (int id){
        Ficheiro encontrado = null;
        synchronized(lista){
            for (Ficheiro ficheiro : lista) {
                if (ficheiro.getId() == id){
                    encontrado = ficheiro;
                    break;
                }
            }
        }
        notifyAll();
        return encontrado;
    }
    
    
    
    
    
    
    
    
    
// A actulizar a local   ////////////////////////////////////////////////// 
    
    /** Actualiza o dominio de um Ficheiro recebendo o id
     * 
     * @param id int com id do Ficheiro
     * @param dominio String com o novo dominio
     * @return Ficheiro actualizado
     */
    public synchronized Ficheiro setDominio(int id, String dominio){
        Ficheiro actualizado = null;
        synchronized(lista){
            for (Ficheiro ficheiro : lista) {
                if (ficheiro.getId() == id){
                    ficheiro.setDominio(dominio);
                    actualizado = ficheiro;
                    break;
                }
            }
        }
        notifyAll();
        return actualizado;
    }
     /** Actualiza nome de um Ficheiro recebendo o id
     * 
     * @param id int com id do Ficheiro
     * @param nome String com novo nome
     * @return Ficheiro actualizado
     */
    public synchronized Ficheiro setFicheiro(int id, String nome){
        Ficheiro actualizado = null;
        synchronized(lista){
            for (Ficheiro ficheiro : lista) {
                if (ficheiro.getId() == id){
                    ficheiro.setFicheiro(nome);
                    actualizado = ficheiro;
                    break;
                }
            }
        }
        notifyAll();
        return actualizado;
    }
     /** Actualiza Estado de um Ficheiro recebendo o id
     * 
     * @param id int com id do Ficheiro 
     * @param estado String com novo estado
     * @return Ficheiro actualizado
     */
    public synchronized Ficheiro setEstado(int id, String estado){
        Ficheiro actualizado = null;
        synchronized(lista){
            for (Ficheiro ficheiro : lista) {
                if (ficheiro.getId() == id){
                    ficheiro.setEstado(estado.toUpperCase());
                    actualizado = ficheiro;
                    break;
                }
            }
        }
        notifyAll();
        return actualizado;
    }
     /** Actualiza Tamanho de um Ficheiro recebendo o id
     * 
     * @param id int com id do Ficheiro 
     * @param tamanho long com o novo tamanho
     * @return Ficheiro actualizado
     */
    public synchronized Ficheiro setTamanhoSite(int id, long tamanho){
        Ficheiro actualizado = null;
        
        synchronized(lista){
            for (Ficheiro ficheiro : lista) {
                if (ficheiro.getId() == id){
                    ficheiro.setTamanhosite(tamanho);
                    actualizado = ficheiro;
                    break;
                }
            }
        }
        notifyAll();
        return actualizado;
    }
     /** Actualiza Caminho no site de um Ficheiro recebendo o id
     * 
     * @param id int com id do Ficheiro 
     * @param camSite String com o novo caminho
     * @return Ficheiro actualizado
     */    
    public synchronized Ficheiro setCaminhoSite(int id, String camSite){
        Ficheiro actualizado = null;
        
        synchronized(lista){
            for (Ficheiro ficheiro : lista) {
                if (ficheiro.getId() == id){
                    ficheiro.setCaminhosite(camSite);
                    actualizado = ficheiro;
                    break;
                }
            }
        }
        notifyAll();
        return actualizado;
    }
     /** Actualiza CaminhoLocal de um Ficheiro recebendo o id
     * 
     * @param id int com id do Ficheiro 
     * @param camLocal String com novo caminho local
     * @return Ficheiro actualizado
     */
    public synchronized Ficheiro setCaminhoLocal(int id, String camLocal){
        Ficheiro actualizado = null;
        
        synchronized(lista){
            for (Ficheiro ficheiro : lista) {
                if (ficheiro.getId() == id){
                    ficheiro.setCaminholocal(camLocal);
                    actualizado = ficheiro;
                    break;
                }
            }
        }
        notifyAll();
        return actualizado;
    }
     /** Actualiza o Tipo de um Ficheiro recebendo o id
     * 
     * @param id int com id do Ficheiro 
     * @param tipo String com o novo tipo de ficheiro
     * @return Ficheiro actualizado
     */
    public synchronized Ficheiro setTipo(int id, String tipo){
        Ficheiro actualizado = null;
        
        synchronized(lista){
            for (Ficheiro ficheiro : lista) {
                if (ficheiro.getId() == id){
                    ficheiro.setTipo(tipo.toUpperCase());
                    actualizado = ficheiro;
                    break;
                }
            }
        }
        notifyAll();
        return actualizado;
    }
     /** Actualiza o numero de Nivies de um Ficheiro recebendo o id
     * 
     * @param id int com id do Ficheiro 
     * @param nivel int com novo nivel
     * @return Ficheiro actualizado
     */
    public synchronized Ficheiro setNiveis(int id, int nivel){
        Ficheiro actualizado = null;
        
        synchronized(lista){
            for (Ficheiro ficheiro : lista) {
                if (ficheiro.getId() == id){
                    ficheiro.setNiveis(nivel);
                    actualizado = ficheiro;
                    break;
                }
            }
        }
        notifyAll();
        return actualizado;
    }
     /** Actualiza Data de um Ficheiro recebendo o id
     * 
     * @param id int com id do Ficheiro 
     * @param data Date com o nova data
     * @return Ficheiro actualizado
     */
    public synchronized Ficheiro setActualizado(int id, Date data){
        Ficheiro actualizado = null;
        
        synchronized(lista){
            for (Ficheiro ficheiro : lista) {
                if (ficheiro.getId() == id){
                    ficheiro.setActualizado(data);
                    actualizado = ficheiro;
                    break;
                }
            }
        }
        notifyAll();
        return actualizado;
    }

//////////////////////////////////////////////
//          METODOS VARIOS                  //
//////////////////////////////////////////////

    /**Devolve AL com todos os FX Incompletos do dominio
     * 
     * @param dominio String com o dominio que se deseja
     * @return ArrayList<Ficheiro> de Ficheiro Incompleto
     */
    public ArrayList<Ficheiro> getListaIncompletos(String dominio) {
        ArrayList<Ficheiro> listaFXIncompletos = new ArrayList<Ficheiro>();
       
        DBAccess bd=new DBAccess();
        
        listaFXIncompletos = bd.getIncompleteByDomain(dominio);

//DEBUG
//        for (Ficheiro fx : listaFXIncompletos) {
//            System.err.println("A lista tem tamanho: "+listaFXIncompletos.size());
//            System.err.println(fx.toString());       
//        }
        return listaFXIncompletos;
    }

    /**Devolve AL com todos os FX já descarregados do dominio
     * 
     * @param dominio String com o dominio que se deseja
     * @return ArrayList<Ficheiro> de Ficheiro Incompleto
     */ 
    public ArrayList getListaCompletos(String dominio) {
        ArrayList<Ficheiro> listaFXCompletos = new ArrayList<Ficheiro>();
       
        DBAccess bd=new DBAccess();
        
        listaFXCompletos = bd.getCompleteByDomain(dominio);

//DEBUG
//        for (Ficheiro fx : listaFXCompletos) {
//            System.err.println("A lista tem tamanho: "+listaFXCompletos.size());
//            System.err.println(fx.toString());       
//        }
        return listaFXCompletos;
    }

     /**Devolve AL com todos os FX com determinado estado do dominio
     * 
     * @param dominio String com o dominio que se deseja
     * @param estado String com o estado do qual se deseja os ficheiros
     * @return ArrayList<Ficheiro> de Ficheiro Incompleto
     */ 
    public ArrayList getListaDominioPorEstado(String dominio, String estado) {
        ArrayList<Ficheiro> listaFXPorEstado = new ArrayList<Ficheiro>();
       
        DBAccess bd=new DBAccess();
        
        listaFXPorEstado = bd.getByDomainStatus(dominio, estado.toUpperCase());
//DEBUG        
//        for (Ficheiro fx : listaFXPorEstado) {
//            System.err.println("A lista tem tamanho: "+listaFXPorEstado.size());
//            System.err.println(fx.toString());       
//        }
        return listaFXPorEstado;
    }

    /**Informa se já existe aquele Ficheiro na BD
     * 
     * @param fx Objecto ficheiro a testar
     * @return True se existe False se nao
     */
    public boolean sqlExisteId(Ficheiro fx){
        DBAccess bd=new DBAccess();
        
        return bd.sqlExisteId(fx);
    }

    /** Informa se já existe Ficheiro por id na BD
     * 
     * @param id int com o ID do ficheiro
     * @return True se existe False se nao
     */
    public boolean sqlExisteId(int id){
        DBAccess bd=new DBAccess();
        
        return bd.sqlExisteId(id);
    }

    /** Devolve um unico ficheiro conforme o id
     * 
     * @param id int com o ID do ficheiro desejado
     * @return Objecto Ficheiro pedido
     */
    public Ficheiro getFicheiroBD (int id){
        DBAccess bd=new DBAccess();
        
        return bd.getFicheiro(id);
    }

    /** Devolve CSV com todos os ficheiro do AL local
     * 
     * @param dominio String com o dominio do qual queremos o CSV
     * @return CSV com lista de todos os fx do dominio
     */
    public String toString(String dominio) {
        String saida = "";
        for (Ficheiro fx : lista) {
            saida += fx.toString();
        }
        return saida;
    }
}
